<!doctype html>
<html>
	<head>
		<meta charset="utf-8">
		<title>server pushの各種方式に対する比較</title>
		<link rel="stylesheet" href="common.css">
		<script src="/javascripts/jquery-1.4.2.min.js"></script>
	</head>
	<body>
		<header>
			<h1>server pushの各種方式に対する比較</h1>
		</header>
		<div id=contents>
			<input type="button" id=btnstop value="stop">
			<hr>
			<div class=clear></div>
			<section class=test>
				<h3>websocket</h3>
				<div id=wstps></div>
				<div id=wstest></div>
			</section>
			<section class=test>
				<h3 id=httptitle>http</h3>
				<div id=httptps></div>
				<div id=httptest></div>
			</section>
		</div>
		<div class=clear></div>
		<footer>
			&copy komasshu (http://twitter.com/komasshu)
		</footer>
		
		<script>
			const INIT = 0, RECEIVING = 1, FINISHED = 2;
			var logger = function(txt) {
				if(window.console)
					console.log(txt);
			}
			
			var showtweet = function(obj, id) {
				if(!document.getElementById(id)) {
					throw("undefined id => "+id);
				}
				var out = "", len = obj.length;
				for(var i = 0; i < len; i++) {
					var _obj = obj[i];
					out += "<b>"+_obj.user+"</b> "+_obj.text+"<hr>";
				}
				$('#'+id).html(out);
			}
			
			var MyModel = function(id) {
				if(!document.getElementById(id))
					return false;
				this.id = id;
				this.data = [];
				this.counter = 0;
				this.status = INIT;
			}
			MyModel.prototype = {
				push : function(obj) {
					this.data.unshift(obj);
					if(this.data.length > 5)
						this.data.pop();
					showtweet(this.data, this.id);
				}
			};
			
			
			//////////////////////
			// websocket
			//////////////////////
			var ws, wstest;
			if (window.WebSocket) {
				wstest = new MyModel('wstest');
				ws = new WebSocket("ws://komasshu.com/streamingapi");
				ws.onopen = function(){
						logger('ws connected.');
				};
				ws.onmessage =  function(recv){
					if(wstest.status != FINISHED)
						wstest.status = RECEIVING;
						
					if (wstest.status == RECEIVING && httptest.status == RECEIVING) {
						wstest.counter++;
						wstest.push(JSON.parse(recv.data));
					}
				};
			} else {
				wstest.status = RECEIVING;
			}

			//////////////////////
			// server-sent events
			//////////////////////
			var http,httptest;
			if (window.EventSource) {
				$('#httptitle').html('Server-Sent Events');
				httptest = new MyModel('httptest');
				http = new EventSource('/cgi-bin/sapi/sapi.cgi');
				http.onmessage = function(ev){
					if(httptest.status != FINISHED)
						httptest.status = RECEIVING;
					
					if (wstest.status == RECEIVING && httptest.status == RECEIVING) {
						httptest.counter++;
						httptest.push(JSON.parse(ev.data));
					}
				};
			} else {
				$('#httptitle').html('XHR Streaming');
				httptest = new MyModel('httptest');
				http = new XMLHttpRequest();
				http.open('get', '/cgi-bin/sapi/sapi.cgi');
				http.send();
				var lastSize = 0;
				
				try {
					http.onreadystatechange = function(){
						if (http.readyState > 2 && http.readyState < 5) {
							if(httptest.status != FINISHED)
								httptest.status = RECEIVING;
							
							var messages = http.responseText.substr(lastSize);
							lastSize = http.responseText.length;

							if (wstest.status == RECEIVING && httptest.status == RECEIVING) {
								httptest.counter++;
								var mesgArr = messages.split("\n");
								var len = mesgArr.length;
								for (var i = 0; i < len; i++) {
									var arr = [];
									if (arr = mesgArr[i].match(/^data: ({.+?})$/)) {
										httptest.push(JSON.parse(arr[1]));
									}
								}
							}
						}
					}
				} catch(e) {
					logger(e);
				}
			}



			////////////////////////
			// closing procedure
			////////////////////////
			var start = parseInt(new Date().getTime());
			var closeAll = function() {
				if (timer) {
					clearTimeout(timer);
					timer = null;
				}
				wstest.status = httptest.status = FINISHED;
				
				var finish = parseInt(new Date().getTime());
				var duration = parseInt((finish - start)/1000);
				
				if(window.WebSocket)
					ws.close();
				if(window.EventSource)
					http.close();
				else
					http.abort();
				$('#wstps').html("num : "+wstest.counter+", duration : "+duration+", "+wstest.counter / duration + " [tweets/sec]");
				$('#httptps').html("num : "+httptest.counter+", duration : "+duration+", "+httptest.counter / duration + " [tweets/sec]");
				
				alert('finish to receive tweets:)');
			}
			
			
			$('#btnstop').click(function(){
				closeAll();
			});
			var timer = setTimeout(closeAll, 10000);
		</script>
	</body>
</html>
